#!/usr/bin/python3
from tkinter import *
from tkinter.ttk import *
import tkinter
from tkinter import messagebox
import tkinter.filedialog as filedialog

from ImageSet import ImageSet
import ImageSet as ImageSetUtil
from ImageTag import ImageTag
from PIL import Image, ImageTk
from SelectImageWindow import SelectImageWindow
import os
from DataSet import DataSet
from LogUtils import logger
import time

"""
主窗口
"""


class MainWindow(tkinter.Tk):

    def __init__(self, minsize):
        super().__init__()
        self.dateSetPath = ""
        self.projectPath = os.getcwd()
        self.projectConfigFilePath = self.projectPath + "/.project.json"
        self.minsize = minsize

        self.imageSet = None
        self.imageTag = None

        self.xmin = 0
        self.ymin = 0
        self.xmax = 0
        self.ymax = 0

        self.xLine = None
        self.yLine = None
        pass

    def layoutWidgets(self):
        '''
        主界面布局
        :return:
        '''
        self.title("数据集管理工具")
        for x in range(12):
            for y in range(8):
                self.columnconfigure(x, weight=1, minsize=self.minsize)  # 设置列的最小宽度
                self.rowconfigure(y, weight=1, minsize=self.minsize)  # 设置行的最小宽度

        s = tkinter.ttk.Style()
        s.configure('Treeview', rowheight=30)  # 设置TreeView的行高
        self.resizable(width=False, height=False)  # 禁止拖拽
        self.geometry("%dx%d+%d+%d" % (self.minsize * 12, self.minsize * 8,
                                       (self.winfo_screenwidth() - self.minsize * 12) / 2,
                                       (self.winfo_screenheight() - self.minsize * 8) / 2))  # 定位窗口大小
        # 左上角工具栏
        self.Frame_LT = tkinter.Frame(self, width=self.minsize * 2, height=self.minsize * 4)
        for x in range(2):
            for y in range(5):
                self.Frame_LT.columnconfigure(x, weight=1)  # 设置列的最小宽度
                self.Frame_LT.rowconfigure(y, weight=1)  # 设置行的最小宽度

        self.Frame_LT.grid(row=0, column=0, rowspan=4, columnspan=2)
        # 左下角照片预览
        self.Frame_LB = tkinter.Frame(self, background="yellow", width=self.minsize * 2, height=self.minsize * 4)
        self.Frame_LB.grid(row=4, column=0, rowspan=4, columnspan=2)
        # 中间图片预览
        self.Frame_C = tkinter.Frame(self, background="blue", cursor="cross", width=self.minsize * 8,
                                     height=self.minsize * 8)
        self.Frame_C.grid(row=0, column=2, rowspan=8, columnspan=8)
        # 右边上工具栏
        self.Frame_RT = tkinter.Frame(self, background="red", width=self.minsize * 2, height=self.minsize * 4)
        for x in range(2):
            for y in range(4):
                self.Frame_RT.columnconfigure(x, weight=1, minsize=self.minsize)  # 设置列的最小宽度
                self.Frame_RT.rowconfigure(y, weight=1, minsize=self.minsize)  # 设置行的最小宽度

        self.Frame_RT.grid(row=0, column=10, rowspan=4, columnspan=2)
        # 右下角类别预览
        self.Frame_RB = tkinter.Frame(self, background="yellow", width=self.minsize * 2, height=self.minsize * 4)
        self.Frame_RB.grid(row=4, column=10, rowspan=4, columnspan=2)

        self.layoutFrame_LT()
        self.layoutFrame_LB()
        self.layoutFrame_RB()
        self.layoutFrame_RT()
        self.layoutFrame_C()

    def layoutFrame_LT(self):
        tkinter.Button(self.Frame_LT, text="打开图集", width=70, height=60, command=self.openImageSet).grid(row=0, column=0,
                                                                                                        sticky=N + S + W + E,
                                                                                                        padx=3,
                                                                                                        pady=6.6)

        self.classificationBtn = tkinter.Button(self.Frame_LT, text="分类存储", width=70, height=60)
        self.classificationBtn.grid(row=0, column=1, sticky=N + S + W + E, padx=3, pady=6.6)

        self.createDateSetBtn = tkinter.Button(self.Frame_LT, text="删除当前照片", width=70, height=60)
        self.createDateSetBtn.grid(row=1, column=0, sticky=N + S + W + E, padx=3, pady=6.6)

        tkinter.Button(self.Frame_LT, text="暂时无功能", width=70, height=60).grid(row=1, column=1, sticky=N + S + W + E,
                                                                              padx=3, pady=6.6)

        self.removeClassBtn = tkinter.Button(self.Frame_LT, text="删除当前类型", width=70, height=60)
        self.removeClassBtn.grid(row=2, column=0, sticky=N + S + W + E, padx=3, pady=6.6)

        self.addClassBtn = tkinter.Button(self.Frame_LT, text="添加类型", width=70, height=60)
        self.addClassBtn.grid(row=2, column=1, sticky=N + S + W + E, padx=3, pady=6.6)

        self.clearTagBtn = tkinter.Button(self.Frame_LT, text="清除本次标注", width=70, height=60, )
        self.clearTagBtn.grid(row=3, column=0, sticky=N + S + W + E, padx=3, pady=6.6)

        self.saveTagBtn = tkinter.Button(self.Frame_LT, text="保存标注", width=70, height=60)
        self.saveTagBtn.grid(row=3, column=1, sticky=N + S + W + E, padx=3, pady=6.6)

        self.lastImageBtn = tkinter.Button(self.Frame_LT, text="上一张", width=70, height=60)
        self.lastImageBtn.grid(row=4, column=0, sticky=N + S + W + E, padx=3, pady=6.6)

        self.nextImageBtn = tkinter.Button(self.Frame_LT, text="下一张", width=70, height=60)
        self.nextImageBtn.grid(row=4, column=1, sticky=N + S + W + E, padx=3, pady=6.6)

        self.progress_LF = tkinter.LabelFrame(self.Frame_LT, text="当前标注进度", fg="#33d9b2", width=70, height=60)
        self.progress_LF.grid(row=5, column=0, columnspan=2, sticky=N + S + W + E, padx=3, pady=6.6)
        self.progress = StringVar()
        self.progress.set("0 / 0")
        tkinter.Label(self.progress_LF, textvariable=self.progress, bg="#34ace0", width=12, height=2).grid(row=0,
                                                                                                           column=0,
                                                                                                           columnspan=3,
                                                                                                           sticky=N + S + W + E,
                                                                                                           padx=3,
                                                                                                           pady=6.6)
        self.locationBtn = tkinter.Button(self.progress_LF, text="定位", width=5, height=2)
        self.locationBtn.grid(row=0, column=3, sticky=N + S + W + E, padx=3, pady=6.6)

    def layoutFrame_LB(self):
        imageListSB = Scrollbar(self.Frame_LB)
        imageListSB.pack(side=RIGHT, fill=BOTH)
        style = tkinter.ttk.Style()
        style.map('Treeview', background=[('selected', '#ff3f34')])
        self.imageListTV = Treeview(self.Frame_LB, height=11, columns="imagePath", show="headings",
                                    yscrollcommand=imageListSB.set)

        self.imageListTV.pack(side=LEFT, fill=BOTH, expand=True)
        imageListSB.config(command=self.imageListTV.yview)
        self.imageListTV.heading("imagePath", text="图片索引")
        self.imageListTV.column("imagePath", anchor=CENTER, )
        self.imageListTV.tag_configure("already_tag", font="Helvetic 10 bold", background="#00cec9")
        self.imageListTV.tag_configure("not_tag", font="Helvetic 10 bold", background="#808e9b")
        self.imageListTV.bind("<<TreeviewSelect>>", self.onSelectImage)

    def layoutFrame_C(self):
        self.imageCanvas = tkinter.Canvas(self.Frame_C, width=self.minsize * 8, height=self.minsize * 8)
        self.imageCanvas.pack(fill=BOTH, expand=True)
        img = Image.open("./image/background.png")
        img = img.resize((800, 800))
        img = ImageTk.PhotoImage(img)
        self.canvas_image = self.imageCanvas.create_image(0, 0, anchor=NW, image=img)
        self.imageCanvas.image = img

    def layoutFrame_RT(self):
        classListRT = Scrollbar(self.Frame_RT)
        classListRT.pack(side=RIGHT, fill=BOTH)
        self.classListTv = Treeview(self.Frame_RT, height=13, columns="classList", show="headings",
                                    yscrollcommand=classListRT.set)
        self.classListTv.pack(side=LEFT, fill=BOTH, expand=True)
        classListRT.config(command=self.classListTv.yview)
        self.classListTv.column("classList", anchor=CENTER)
        self.classListTv.heading("classList", text="选择预标注")
        self.classListTv.tag_configure("imageFont", font="Helvetic 15 bold")
        self.classListTv.bind("<<TreeviewSelect>>", self.onSelectClass)

    def layoutFrame_RB(self):
        imageListRB = Scrollbar(self.Frame_RB)
        imageListRB.pack(side=RIGHT, fill=BOTH)
        self.labelListTv = Treeview(self.Frame_RB, height=11, columns="labelList", show="headings",
                                    yscrollcommand=imageListRB.set)
        self.labelListTv.pack(side=LEFT, fill=BOTH, expand=True)
        imageListRB.config(command=self.labelListTv.yview)
        self.labelListTv.column("labelList", anchor=CENTER, )
        self.labelListTv.heading("labelList", text="标注记录")

    def topSaveTag(self):
        """
        提醒用户，保存标注
        :return:
        """
        askyesno = messagebox.askyesno(title="提示", message="您还未保存本次标注，是否线保存本次标注")
        if askyesno:
            self.saveTag()
        self.focus_force()

    def classification(self):
        """
        分类存储
        """
        print("照片个数" + str(len(self.imageSet.get_Image_Path_List())))
        print("xml个数" + str(len(self.imageSet.get_Xml_Path_List())))
        if len(self.imageSet.get_Image_Path_List()) == len(self.imageSet.get_Xml_Path_List()):
            # 当全部标注完成才可分类
            savePath = filedialog.askdirectory()
            if os.path.exists(savePath):
                self.imageSet.classificationSave(savePath)
            else:
                messagebox.showinfo(title="提示", message="未选择路径")
        else:
            messagebox.showinfo(title="提示", message="未全部标注完成，不可分类")
        pass

    def removeCurrentImage(self):
        """
        删除当前图片
        """
        if self.imageSet.getIsAllowDeleteImage():
            # 允许使用删除功能
            pass
        else:
            # 不允许使用删除功能
            pass
        pass

    def initButtonEvent(self):
        self.classificationBtn.config(command=self.classification)
        self.classificationBtn.command = self.classification

        self.createDateSetBtn.config(command=self.removeCurrentImage)
        self.createDateSetBtn.command = self.removeCurrentImage

        self.removeClassBtn.config(command=self.removeClass)
        self.removeClassBtn.command = self.removeClass

        self.addClassBtn.config(command=self.addClass)
        self.addClassBtn.command = self.addClass

        self.clearTagBtn.config(command=self.clearTag)
        self.clearTagBtn.command = self.clearTag

        self.saveTagBtn.config(command=self.saveTag)
        self.saveTagBtn.command = self.saveTag

        self.lastImageBtn.config(command=self.lastImage)
        self.lastImageBtn.command = self.lastImage
        self.nextImageBtn.config(command=self.nextImage)
        self.nextImageBtn.command = self.nextImage

        self.locationBtn.config(command=self.location)
        self.locationBtn.command = self.location
        # 绑定界面绘图事件
        self.imageCanvas.bind("<Button-1>", self.press_mouse)
        self.imageCanvas.bind("<B1-Motion>", self.move_mouse)
        self.imageCanvas.bind("<ButtonRelease-1>", self.release_mouse)
        # 鼠标绘制
        self.imageCanvas.bind('<Enter>', self.create_line)
        self.imageCanvas.bind('<Leave>', self.delete_line)
        # 快捷键
        # 撤回标注快捷键
        self.bind('<Control-z>', self.keyboardCall)
        self.bind('<Command-z>', self.keyboardCall)
        self.bind("<Up>", self.keyboardCall)
        self.bind("<Down>", self.keyboardCall)
        # 按空格或s或回车下一张快捷键
        self.bind('<s>', self.keyboardCall)
        self.bind('<space>', self.keyboardCall)
        self.bind('<Return>', self.keyboardCall)

    def keyboardCall(self, event):
        # TODO:响应用户快捷键
        logger.debug("使用快捷键{0}".format(str(event)))
        if event.keysym == "s" or event.keysym == "space" or event.keysym == "Return":
            self.saveTag()
            self.imageSet.addCurrentImageIndex()
            self.__updateImageCanvas()

        if event.keysym == 'z':
            self.clearTag()
        if event.keysym == 'Up':
            self.lastImage()
        if event.keysym == 'Down':
            self.nextImage()

    def create_line(self, event):
        if event.x > -10 and event.x < self.minsize * 8 + 10 and event.y > -10 and event.y < self.minsize * 8 + 10:
            self.imageCanvas.bind('<Motion>', self.draw_line)
            self.xLine = self.imageCanvas.create_line(0, event.y, self.minsize * 8, event.y, fill="#fffa65")
            self.yLine = self.imageCanvas.create_line(event.x, 0, event.x, self.minsize * 8, fill="#fffa65")

    def delete_line(self, event):
        self.imageCanvas.unbind('<Motion>')
        self.imageCanvas.delete(self.xLine)
        self.imageCanvas.delete(self.yLine)
        self.xLine = None
        self.yLine = None

    def draw_line(self, event):

        if event.x < 0 and event.x > self.minsize * 8 and event.y < 0 and event.y > self.minsize * 8:
            self.imageCanvas.unbind('<Motion>')
        self.imageCanvas.coords(self.xLine, 0, event.y, self.minsize * 8, event.y)
        self.imageCanvas.coords(self.yLine, event.x, 0, event.x, self.minsize * 8)

    # def createDateSet(self):
    #     """
    #     创建数据集 TODO:创建数据集
    #     :return:
    #     """
    #
    #     def confirmCallback(fileName, entry):
    #         resultPath = filedialog.askdirectory()
    #         logger.debug("选择的数据集路径为：{0}".format(resultPath))
    #         if len(resultPath) == 0:
    #             messagebox.showinfo("error", "操作失败，您未选择路径")
    #             return
    #         dataSetPath = resultPath + "/" + fileName
    #         if os.path.exists(dataSetPath):
    #             logger.debug("文件存在")
    #         else:
    #             os.mkdir(dataSetPath)
    #         logger.debug("数据集路径为 {0}".format(dataSetPath))
    #         dataSet = DataSet(dataSetPath)
    #         dataSet.writeClassName(self.imageSet.get_Class_Name_List())  # 写入了类型
    #         selectImageWindows = SelectImageWindow(dataSet, self.imageSet.get_The_Labeled_Image())
    #         selectImageWindows.focus_force()
    #         selectImageWindows.mainloop()
    #
    #     self.showMessage("给数据集文件命名", "输入", confirmCallback, lambda: logger.debug("取消命名"))
    #     pass

    def location(self):
        """
        定位到最近的未标注的图片
        :return:
        """
        # self.saveTag()
        self.imageSet.locationImage()
        self.imageListTV.selection_set(self.imageSet.getCurrentImageIndex())
        self.imageListTV.see(self.imageSet.getCurrentImageIndex())
        pass

    def removeClass(self):
        """
        删除当前类型的响应方法
        :return:
        """
        askyesno = messagebox.askyesno(title="提醒", message="确认删除当前类型？")
        logger.debug("是否确认删除{0}".format(askyesno))
        if askyesno:
            self.classListTv.delete(*self.classListTv.get_children())
            self.imageSet.delete_Class_Name_To_Profile(self.imageSet.getCurrentClassIndex())
            self.fillClassListTV()
            logger.debug("删除成功")
        pass

    def addClass(self):
        """
        添加类型
        :return:
        """

        def confirmCallback(className, weight, color):
            if not self.imageSet.check_Class_Name_Exist(className):  # 如果添加的类型不存
                self.classListTv.insert("", iid=len(self.imageSet.get_Class_Name_List()), index=END, values=className,
                                        tags="imageFont")
                self.imageSet.add_Class_Name_To_Profile(className, int(weight), color)
                self.classListTv.selection_set(self.imageSet.getCurrentClassIndex())
                self.classListTv.see(self.imageSet.getCurrentClassIndex())
                self.labelListTv.tag_configure(color, font="Helvetic 15 bold", background=color) #添加标签颜色
            logger.debug("添加类型成功")

        self.showMessage("添加类型", "输入类型", confirmCallback, lambda: logger.debug("取消添加类型"))
        pass

    def saveTag(self):
        # TODO:弹出消息提示
        self.imageTag.saveTagXml()

        self.updateTitleMessage(tip="已保存")
        seletedIID = self.imageListTV.selection()
        self.imageListTV.item(seletedIID, tags="already_tag")
        self.imageSet.add_Xml_Path_To_List(self.imageTag.getXmlPath())
        # self.progress.set(
        #     "{0} / {1}".format(len(self.imageSet.get_Xml_Path_List()), len(self.imageSet.get_Image_Path_List())))

    def clearTag(self):
        # 将标签和矩形框出栈
        logger.debug("是否点击出栈按钮")
        rect = self.imageTag.popLabelAndRect()
        logger.debug("清除本次标注 {0}".format(rect))
        if self.imageSet.check_current_image_is_tag():
            self.updateTitleMessage(tip="存在标注文件，删除了标注，未保存")
        else:
            self.updateTitleMessage(tip="不存在标注文件，删除了标注，未保存")
        logger.debug("Label和Rect入栈成功")
        if rect is not None:
            if self.imageSet.check_current_image_is_tag():
                self.updateTitleMessage(tip="存在标注文件，标注为空，未保存")
            else:
                self.updateTitleMessage(tip="不存在标注文件，标注为空，未保存")
            self.imageCanvas.delete(rect)
            self.labelListTv.delete(len(self.imageTag.getLabelList()))

    def clearAllLabelListTv(self):
        """
        清除右下角标签框中内容
        :return:
        """
        x = self.labelListTv.get_children()
        for item in x:
            self.labelListTv.delete(item)

    # 响应事件
    def onSelectImage(self, event):
        # TODO:主要更新方法
        """
        发生照片切换事件，上一张，下一张，点击切换最终都需要经过这个方法
        :param event:
        :return:
        """
        # 清除上次标注的label
        self.clearAllLabelListTv()
        self.imageCanvas.delete(tkinter.ALL)
        widgetObj = event.widget
        itemSelected = widgetObj.selection()[0]
        current = int(itemSelected)
        self.imageSet.setCurrentImageIndex(current)
        self.progress.set(
            "{0} / {1}".format(self.imageSet.getCurrentImageIndex(),
                               len(self.imageSet.get_Image_Path_List()) - 1))

        # 初始化imageTag
        self.imageTag = ImageTag(self.imageSet.getCurrent_Image_Path(), 800)
        # 更新标题
        if self.imageSet.check_current_image_is_tag():
            self.updateTitleMessage(tip="已存在标注文件")
        else:
            self.updateTitleMessage(tip="不存在标注文件")
        #  更新背景图片
        self.imageCanvas.delete(self.canvas_image)
        self.canvas_image = self.imageCanvas.create_image(0, 0, anchor=NW, image=self.imageTag.getImage())
        self.imageCanvas.image = self.imageTag.getImage()
        ##TODO:此处不能够调用这两个选中的方法，会造成死循环，
        # self.imageListTV.selection_set(self.imageSet.getCurrentIndex())
        # self.imageListTV.see(self.imageSet.getCurrentIndex())
        # 显示已经有的矩形框
        for index, label in enumerate(self.imageTag.getLabelList()):
            logger.debug("读取到已经存在的标注为{0}".format(label))
            self.color = self.imageSet.getColorFromClass(label["name"])
            rect = self.imageCanvas.create_rectangle(label["xmin"], label["ymin"], label["xmax"], label["ymax"],
                                                     outline=self.color, width=2)
            self.imageTag.pushRect(rect)
            self.labelListTv.insert("", iid=index, index=END, values=label["name"], tags=self.color)  # 添加左下角标签框内容
        self.imageTag.checkLabelAndRect()

    def onSelectClass(self, event):
        """
        选择类型
        :param event:
        :return:
        """
        widgetObj = event.widget
        itemSelected = widgetObj.selection()[0]
        current = int(itemSelected)  # 选择的类型的index
        self.imageSet.setCurrentClassIndex(current)

    def updateTitleMessage(self, tip=""):
        strMessage = self.imageSet.getCurrent_Image_Path() + tip
        self.title(strMessage)

    def lastImage(self):
        # TODO:切换上一张
        # self.saveTag()

        if not self.imageTag.IsSave():
            self.topSaveTag()
        self.imageSet.reduceCurrentImageIndex()
        self.__updateImageCanvas()

    def nextImage(self):
        # TODO:切换下一张
        # 当标注过多切换图片会出现明显卡顿
        # self.saveTag()

        if not self.imageTag.IsSave():
            self.topSaveTag()
        self.imageSet.addCurrentImageIndex()
        self.__updateImageCanvas()

    def openImageSet(self):
        self.imageSetPath = filedialog.askdirectory(title="选择图片集", parent=self)
        logger.debug("选择的图片集路径为 {0}".format(self.imageSetPath))
        if len(self.imageSetPath) == 0:
            messagebox.showinfo("error", "操作失败，您未选择路径")
        else:
            self.title(self.imageSetPath)
            self.imageSet = ImageSet(self.imageSetPath)
            if len(self.imageSet.get_Image_Path_List()) == 0:
                messagebox.showinfo("错误", "当前目录下没有图片")
            else:

                # self.progress.set(
                #     "{0} / {1}".format(len(self.imageSet.get_Xml_Path_List()),
                #                        len(self.imageSet.get_Image_Path_List())))
                self.fillImageListTV()
                self.fillClassListTV()

                self.__updateImageCanvas()
                self.initButtonEvent()

    # 图片标注相关响应方法
    def press_mouse(self, event):
        self.xmin = event.x
        self.ymin = event.y
        logger.debug("按下鼠标 {0} ,{1}".format(self.xmin, self.ymin))
        self.color = self.imageSet.getColorFromClass(self.imageSet.getCurrentClassName())
        self.currentRect = self.imageCanvas.create_rectangle(self.xmin, self.ymin, self.xmin, self.ymin,
                                                             outline=self.color)

    def move_mouse(self, event):
        self.imageCanvas.coords(self.xLine, 0, event.y, self.minsize * 8, event.y)
        self.imageCanvas.coords(self.yLine, event.x, 0, event.x, self.minsize * 8)
        x, y = 0, 0
        if event.x > 800:
            x = 800 - 5
        elif event.x < 0:
            x = 0 + 5
        else:
            x = event.x
        if event.y > 800:
            y = 800 - 5
        elif event.y < 0:
            y = 0 + 5
        else:
            y = event.y

        self.imageCanvas.coords(self.currentRect, self.xmin, self.ymin, x, y)

    def release_mouse(self, event):
        self.xmax = event.x
        self.ymax = event.y
        if event.x > 800:
            self.xmax = 799
        elif event.x <= 0:
            self.xmax = 1
        else:
            self.xmax = event.x

        if event.y >= 800:
            self.ymax = 799
        elif event.y <= 0:
            self.ymax = 1
        else:
            self.ymax = event.y

        logger.debug("松开鼠标，检查坐标({0},{1}) --> ({2},{3})".format(self.xmin, self.ymin, self.xmax, self.ymax))
        self.labelListTv.insert("", iid=len(self.imageTag.getLabelList()), index=END,
                                values=self.imageSet.getCurrentClassName(),
                                tags=self.imageSet.getColorFromClass(self.imageSet.getCurrentClassName()))  # 添加左下角标签框内容
        assert 0 < self.xmin < 800
        assert 0 < self.xmax < 800
        assert 0 < self.ymin < 800
        assert 0 < self.ymax < 800
        self.imageTag.pushLabelAndRect(
            [self.imageSet.getCurrentClassName(), self.xmin, self.ymin, self.xmax, self.ymax], self.currentRect)
        # TODO:
        if self.imageSet.check_current_image_is_tag():
            self.updateTitleMessage(tip="存在标注文件，添加了标注，未保存")
        else:
            self.updateTitleMessage(tip="不存在标注文件，添加了标注，未保存")
        logger.debug("Label和Rect入栈成功")

    def showMessage(self, title, message1, confirmCallback, cancelCallback):
        """
        显示类别提示框
        :param title: 标题
        :param message: 输入框的提示信息
        :param confirmCallback: 确认回调
        :param cancelCallback: 取消回调
        :return:
        """
        toplevel = Toplevel()
        toplevel.geometry(
            "%dx%d+%d+%d" % (290, 160, (self.winfo_screenwidth() - 290) / 2, (self.winfo_screenheight() - 160) / 2))
        toplevel.title(title)
        for x in range(3):
            for y in range(4):
                toplevel.columnconfigure(x, weight=1, )  # 设置列的最小宽度
                toplevel.rowconfigure(y, weight=1, )  # 设置行的最小宽度

        toplevel.attributes("-topmost", True)
        Label(toplevel, text=message1).grid(row=0, column=0, pady=5, padx=10)
        entry1 = Entry(toplevel)
        entry1.grid(row=0, column=1, columnspan=3, sticky=W, pady=5, padx=10)

        Label(toplevel, text="输入权重").grid(row=1, column=0, pady=5, padx=10)
        entry2 = Entry(toplevel)
        entry2.grid(row=1, column=1, columnspan=3, sticky=W, pady=5, padx=10)

        Label(toplevel, text="输入颜色").grid(row=2, column=0, pady=5, padx=10)
        entry3 = Entry(toplevel)
        entry3.grid(row=2, column=1, columnspan=3, sticky=W, pady=5, padx=10)

        # else:
        #     Label(toplevel, text=message1).grid(row=0, rowspan=2, column=0, pady=5, padx=10)
        #     entry1 = Entry(toplevel)
        #     entry1.grid(row=0, rowspan=2, column=1, columnspan=3, sticky=W, pady=5, padx=10)

        def confirm():
            entryText1 = entry1.get()
            entryText2 = entry2.get()
            entryText3 = entry3.get()
            confirmCallback(entryText1, entryText2, entryText3)
            toplevel.destroy()

        def cancel():
            cancelCallback()
            toplevel.destroy()

        Button(toplevel, text="确认", command=confirm).grid(row=3, column=0, columnspan=2, pady=10, padx=10)
        Button(toplevel, text="取消", command=cancel).grid(row=3, column=2, columnspan=2, pady=10, padx=10)

    # 界面变化
    def fillImageListTV(self):
        """
        填充左下角ImageTreeView
        :param imagePathList:
        :return:
        """
        for (index, item) in enumerate(self.imageSet.get_Image_Path_List()):
            if ImageSetUtil.check_Image_is_tag(item):  # 检查xml文件是否存在
                self.imageListTV.insert("", iid=index, index=END, values=os.path.relpath(item, self.imageSetPath),
                                        tags="already_tag")
            else:
                self.imageListTV.insert("", iid=index, index=END, values=os.path.relpath(item, self.imageSetPath),
                                        tags="not_tag")

    def fillClassListTV(self):
        for (index, item) in enumerate(self.imageSet.get_Class_Name_List()):
            self.classListTv.insert("", iid=index, index=END, values=item, tags="imageFont")
        self.classListTv.selection_set(self.imageSet.getCurrentClassIndex())
        self.classListTv.see(self.imageSet.getCurrentClassIndex())

    def __updateImageCanvas(self):
        """
        主要的更新照片的方法
        :return:
        """
        # 初始化imageTag
        logger.debug("--------------------------------------------------------------------")
        for color in self.imageSet.getColorFromAll():
            self.labelListTv.tag_configure(color, font="Helvetic 15 bold", background=color)

        self.imageListTV.selection_set(self.imageSet.getCurrentImageIndex())
        self.imageListTV.see(self.imageSet.getCurrentImageIndex())


if __name__ == '__main__':
    window = MainWindow(100)
    window.layoutWidgets()
    window.mainloop()
